const { getTime } = require("../../utils/gettime")
const testpaper = require("../../model/examination/testpaper")
const { checkNull, handleNumber, isJson, checkMail, checkTimeStamp } = require("../../rules/verification");
const turnTime = require("../../utils/turnTime")

const checkTime = (start, end) => {
    if (start >= end) {
        return { msg: "开始答题时间不能晚于交卷时间！", code: "400" }
    } else if (end - start < 2400000) {
        return { msg: "答题时间最少为四十分钟！", code: "400" }
    } else {
        return { start, end }
    }
}

// 根据id获取试卷
exports.getById = async ({ id }) => {
    try {
        let paper = await testpaper.findOne({ where: { id }, attributes: ["title", "starttime", "endtime", "totalscore", "choicetotal", "answertotal", "conpletiontotal", "judgetotal"] })
        if (!paper) return { msg: "获取试卷失败", code: "400" }
        let parameter = await testpaper.findOne({ where: { id }})
        let question = {}
        if (parameter.choice) {
            let id = JSON.parse(parameter.choice)
            let choiceList = await choice.findAll({ where: { id }, attributes: ["title", "options"] })
            if (!choiceList) return { msg: "获取试卷选择题失败", code: "400" }
            choiceList.forEach(item => {
                item.options = JSON.parse(item.options)
                // 选择题选项创新排列
                item.options.sort(function () {
                    return Math.random() - 0.5;
                })
            });
            // question.push(...choiceList)
            question.choice = choiceList
        }
        if (parameter.answer) {
            let id = JSON.parse(parameter.answer)
            let event = await answer.findAll({ where: { id }, attributes: ["title"] })
            if (!event) return { msg: "获取试卷简答题题失败", code: "400" }
            // question.push(...event)
            question.answer = event
        }
        if (parameter.conpletion) {
            let id = JSON.parse(parameter.conpletion)
            let event = await conpletion.findAll({ where: { id }, attributes: ["title"] })
            if (!event) return { msg: "获取试卷填空题失败", code: "400" }
            // question.push(...event)
            question.conpletion = event
        }
        if (parameter.judge) {
            let id = JSON.parse(parameter.judge)
            let event = await judge.findAll({ where: { id }, attributes: ["title"] })
            if (!event) return { msg: "获取试卷判断题失败", code: "400" }
            // question.push(...event)
            question.judge = event
        }
        paper.question = question
        paper.starttime = turnTime(Number(paper.starttime))
        paper.endtime = turnTime(Number(paper.endtime))
        let data = {}
        data.title = paper.title
        data.starttime = paper.starttime
        data.endtime = paper.endtime
        data.totalscore = paper.totalscore
        data.choicetotal = paper.choicetotal
        data.answertotal = paper.answertotal
        data.conpletiontotal = paper.conpletiontotal
        data.judgetotal = paper.judgetotal
        data.question = question;
        if (data) return { msg: "获取试卷成功", code: "200", data }
        return { msg: "获取试卷失败", code: "400" }
    } catch (err) {  return { msg: "获取试卷失败", code: "400", err } }
}

// 获取试卷列表
exports.getList = async ({ pageNum, pageSize }) => {
    try {
        let res = await testpaper.findAndCountAll({
            offset: pageNum * pageSize - pageSize,
            limit: pageSize,
            attributes: ["id", "title", "cover", "createdate", "creator", "updated", "updator"]
        })
        if (res) return { msg: "获取试卷列表成功", code: "200", data: res }
        return { msg: "获取试卷列表失败", code: "400" }
    } catch (err) { return { msg: "获取试卷列表失败", code: "400", err } }
}

// 添加试卷
exports.create = async ({ title, creator, choice, answer, judge, conpletion, starttime, endtime, choicebranch, answerbranch, conpletionbranch, judgebranch }) => {
    try {
        let isCreate = await testpaper.findOne({ where: { title } })
        if (isCreate) return { msg: "重复的试卷标题", code: "400" }
        let checkedTime = checkTime(starttime, endtime)
        if (checkedTime.code === "400") return checkedTime
        let forQuestionArr = [
            { question: choice, message: "选择题", branch: choicebranch },
            { question: answer, message: "简答题", branch: answerbranch },
            { question: judge, message: "填空题", branch: judgebranch },
            { question: conpletion, message: "判断题", branch: conpletionbranch },
        ]
        // 总题数数组
        let questionArr = []
        // 总分
        let totalscore = 0;
        // 选择题分数
        let choicetotal = 0;
        // 简答题分数
        let answertotal = 0;
        // 填空题分数
        let judgetotal = 0;
        // 判断题分数
        let conpletiontotal = 0;
        // 验证试题索引数组是否为 JSON 格式 
        // 计算 总分、大题分数
        try {
            forQuestionArr.forEach(item => {
                if (item.question) {
                    let checkedJson = isJson(item.question, item.message + "索引数组")
                    if (checkedJson.code !== "200") throw new Error(JSON.stringify(checkedJson));
                    let sum = JSON.parse(JSON.parse(checkedJson.data)).length
                    item.question = JSON.parse(item.question)
                    let target = checkNull(item.branch, item.message + "分数")
                    if (target.code !== "200") throw new Error(JSON.stringify(target))
                    totalscore += sum * target.data
                    switch (item.message) {
                        case "选择题": choicetotal = sum * target.data || ""; break;
                        case "简答题": answertotal = sum * target.data || ""; break;
                        case "判断题": judgetotal = sum * target.data || ""; break;
                        case "填空题": conpletiontotal = sum * target.data || ""; break;
                    }
                    questionArr.push(...item.question)
                }
            })
        } catch (e) {
            let str = e.toString();
            if (str.length > 7) {
                str = str.substr(7);
            } else {
                str = `{"msg":"未知错误","code":"400"}`;
            }
            // return JSON.parse(str);
        }
        if (questionArr.length <= 0) return { msg: "题量不足 无法添加", code: "400" }
        let newData = {}
        if (creator) newData.creator = creator
        if (typeof choice == "object") {
            choice = JSON.stringify(choice)
        }
        // if (choice) newData.choice = choice
        if (typeof answer == "object") { 
            answer = JSON.stringify(answer)
        }
        if (answer) {
            if (!answerbranch) return { msg: "请设置简答题单题分数", code: "400" }
            newData.answer = answer
            newData.answerbranch = answerbranch
        }
        if (judge) {
            if (!judgebranch) return { msg: "请设置判断题单题分数", code: "400" }
            newData.judge = judge
            newData.judgebranch = judgebranch
        }
        if (conpletion) {
            if (!conpletionbranch) return { msg: "请设置填空题单题分数", code: "400" }
            newData.conpletion = conpletion
            newData.conpletionbranch = conpletionbranch
        }
        if (choice) {
            if (!choicebranch) return { msg: "请设置选择题单题分数", code: "400" }
            newData.choice = choice
            newData.choicebranch = choicebranch
        }
        if (judge) newData.judge = judge
        if (conpletion) newData.conpletion = conpletion
        if (choicetotal) newData.choicetotal = choicetotal
        if (answertotal) newData.answertotal = answertotal
        if (judgetotal) newData.judgetotal = judgetotal
        if (conpletiontotal) newData.conpletiontotal = conpletiontotal
        newData.title = title
        newData.starttime = starttime
        newData.endtime = endtime
        newData.totalscore = totalscore
        newData.starttime = starttime
        newData.endtime = endtime
        // newData.createdate = getTime()

        let res = await testpaper.create(newData)
        if (res) return { msg: "添加试卷成功", code: "200" }
        return { msg: "添加试卷失败", code: "400" }
    } catch (err) { return { msg: "添加试卷失败", code: "400", err } }
}

// 编辑试卷
exports.edit = async ({ id, title, updator, choice, answer, judge, conpletion, starttime, endtime, choicebranch, answerbranch, conpletionbranch, judgebranch }) => {
    try {
        let checkedId = checkNull(id, "试卷 Id")
        if (checkedId.code !== "200") return checkedId
        let newData = {};
        if (title) {
            let isUpdate = await testpaper.findOne({ where: { title }, attributes: ["id"] })
            if (isUpdate) {
                if (isUpdate.id != id) return { msg: "重复的试卷名称", code: "400" }
                newData.title = title
            } else {
                newData.title = title
            }
        }
        let param = [
            { name: "choice", data: choice, message: "选择题索引数组" },
            { name: "answer", data: answer, message: "简答题索引数组" },
            { name: "judge", data: judge, message: "判断题索引数组" },
            { name: "conpletion", data: conpletion, message: "填空题索引数组" }
        ]
        let choiceStr;
        let answerStr;
        let judgeStr;
        let conpletionStr;
        try {
            param.forEach(item => {
                if (item.data) {
                    let checkedItem = isJson(item.data, item.message)
                    if (checkedItem.code !== "200") throw new Error(JSON.stringify(checkedItem))
                    switch (item.name) {
                        case "choice": choiceStr = JSON.parse(checkedItem.data); break;
                        case "answer": answerStr = JSON.parse(checkedItem.data); break;
                        case "judge": judgeStr = JSON.parse(checkedItem.data); break;
                        case "conpletion": conpletionStr = JSON.parse(checkedItem.data); break;
                    }
                }
            })
        } catch (err) {
            let str = err.toString()
            if (str.length > 7) {
                str = str.substr(7)
            } else {
                str = `{"msg":"未知错误","code":"400"}`
            }
            return JSON.parse(str)
        }

        if (answerStr) {
            if (!answerbranch) return { msg: "请设置简答题单题分数", code: "400" }
            newData.answer = answerStr
            newData.answerbranch = answerbranch
        }
        if (judgeStr) {
            if (!judgebranch) return { msg: "请设置判断题单题分数", code: "400" }
            newData.judge = judgeStr
            newData.judgebranch = judgebranch
        }
        if (conpletionStr) {
            if (!conpletionbranch) return { msg: "请设置填空题单题分数", code: "400" }
            newData.conpletion = conpletionStr
            newData.conpletionbranch = conpletionbranch
        }
        if (choiceStr) {
            if (!choicebranch) return { msg: "请设置选择题单题分数", code: "400" }
            newData.choice = choiceStr
            newData.choicebranch = choicebranch
        }
        if (updator) newData.updator = updator
        newData.updated = getTime()
        if (starttime) {
            let checkedStart = checkTimeStamp(starttime, "开始答题时间戳")
            if (checkedStart.code !== "200") return checkedStart
            if (endtime) {
                let checkedEnd = checkTimeStamp(endtime, "收卷时间戳")
                if (checkedEnd.code !== "200") return checkedEnd
                let checktime = checkTime(checkedStart.data, checkedEnd.data)
                if (checktime.code == "400") return checktime
                newData.starttime = checktime.start
                newData.endtime = checktime.end
            } else {
                let time = await testpaper.findOne({ where: { id }, attributes: ["endtime"] })
                let checktime = checkTime(checkedStart.data, time.endtime)
                if (checktime.code == "400") return checktime
                newData.starttime = checktime.start
                newData.endtime = checktime.end
            }
        } else {
            if (endtime) {
                let checkedEnd = checkTimeStamp(endtime, "收卷时间戳")
                if (checkedEnd.code !== "200") return checkedEnd
                let time = await testpaper.findOne({ where: { id }, attributes: ["starttime"] })
                let checktime = checkTime(checkedStart.data, time.starttime)
                if (checktime.code == "400") return checktime
                newData.starttime = checktime.start
                newData.endtime = checktime.end
            }
        }
        let res = await testpaper.update(newData, { where: { id } })
        if (res) return { msg: "更新试卷成功", code: "200" }
        return { msg: "更新试卷失败", code: "400" }
    } catch (err) { return { msg: "编辑试卷失败", code: "400", err } }
}

// 删除试卷
exports.remove = async ({ id }) => {
    try {
        let checkedId = checkNull(id, "试卷id")
        if (checkedId.code !== "200") return checkedId
        let res = await testpaper.destroy({ where: { id } })
        if (res) return { msg: "删除试卷成功", code: "200" }
        return { msg: "删除试卷失败", code: "400" }
    } catch (err) { return { msg: "删除试卷失败", code: "400", err } }
}